{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "df5293c8-0f35-4837-82bc-62ae2741dcf0",
   "metadata": {},
   "source": [
    "# Import packages and connect to Elasticsearch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3759dd45-7c54-40e7-b236-0745fb3d14f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'liuxgm.local', 'cluster_name': 'elasticsearch', 'cluster_uuid': 'h2QwONxsT4Kt-lTRKmPrhg', 'version': {'number': '8.12.0', 'build_flavor': 'default', 'build_type': 'tar', 'build_hash': '1665f706fd9354802c02146c1e6b5c0fbcddfbc9', 'build_date': '2024-01-11T10:05:27.953830042Z', 'build_snapshot': False, 'lucene_version': '9.9.1', 'minimum_wire_compatibility_version': '7.17.0', 'minimum_index_compatibility_version': '7.0.0'}, 'tagline': 'You Know, for Search'}\n"
     ]
    }
   ],
   "source": [
    "from elasticsearch import Elasticsearch\n",
    "from dotenv import load_dotenv\n",
    "import os\n",
    "\n",
    "load_dotenv()\n",
    " \n",
    "openai_api_key=os.getenv('OPENAI_API_KEY')\n",
    "elastic_user=os.getenv('ES_USER')\n",
    "elastic_password=os.getenv('ES_PASSWORD')\n",
    "elastic_endpoint=os.getenv(\"ES_ENDPOINT\")\n",
    " \n",
    "url = f\"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200\"\n",
    "client = Elasticsearch(url, ca_certs = \"./http_ca.crt\", verify_certs = True)\n",
    " \n",
    "print(client.info())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b449c772-d72d-492d-9465-e30d86099dba",
   "metadata": {},
   "source": [
    "# Index some test data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "2a031861-84fe-4762-91e0-6684e4e68353",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ObjectApiResponse({'errors': False, 'took': 87, 'items': [{'index': {'_index': 'products_index', '_id': 'us1', '_version': 1, 'result': 'created', 'forced_refresh': True, '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 0, '_primary_term': 1, 'status': 201}}, {'index': {'_index': 'products_index', '_id': 'uk1', '_version': 1, 'result': 'created', 'forced_refresh': True, '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 1, '_primary_term': 1, 'status': 201}}, {'index': {'_index': 'products_index', '_id': 'eu1', '_version': 1, 'result': 'created', 'forced_refresh': True, '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 2, '_primary_term': 1, 'status': 201}}, {'index': {'_index': 'products_index', '_id': 'preview1', '_version': 1, 'result': 'created', 'forced_refresh': True, '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 3, '_primary_term': 1, 'status': 201}}]})"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import json\n",
    "\n",
    "# Load data into a JSON object\n",
    "with open('query-rules-data.json') as f:\n",
    "   docs = json.load(f)\n",
    "\n",
    "operations = []\n",
    "for doc in docs:\n",
    "    operations.append({\"index\": {\"_index\": \"products_index\", \"_id\": doc[\"id\"]}})\n",
    "    operations.append(doc[\"content\"])\n",
    "client.bulk(index=\"products_index\", operations=operations, refresh=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f633ae03-7756-4c2a-bc37-b1cf4f01676a",
   "metadata": {},
   "source": [
    "# Search the test data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "66e81616-f861-444a-ae23-8b2d1311f452",
   "metadata": {},
   "outputs": [],
   "source": [
    "def pretty_response(response):\n",
    "    if len(response['hits']['hits']) == 0:\n",
    "        print('Your search returned no results.')\n",
    "    else:\n",
    "        for hit in response['hits']['hits']:\n",
    "            id = hit['_id']\n",
    "            score = hit['_score']\n",
    "            name = hit['_source']['name']\n",
    "            description = hit['_source']['description']\n",
    "            price = hit[\"_source\"][\"price\"]\n",
    "            currency = hit[\"_source\"][\"currency\"]\n",
    "            plug_type = hit[\"_source\"][\"plug_type\"]\n",
    "            voltage = hit[\"_source\"][\"voltage\"]\n",
    "            pretty_output = (f\"\\nID: {id}\\nName: {name}\\nDescription: {description}\\nPrice: {price}\\nCurrency: {currency}\\nPlug type: {plug_type}\\nVoltage: {voltage}\\nScore: {score}\")\n",
    "            print(pretty_output)\n",
    "\n",
    "def pretty_ruleset(response):\n",
    "    print(\"Ruleset ID: \" + response['ruleset_id'])\n",
    "    for rule in response['rules']:\n",
    "        rule_id = rule['rule_id']\n",
    "        type = rule['type']\n",
    "        print(f\"\\nRule ID: {rule_id}\\n\\tType: {type}\\n\\tCriteria:\")\n",
    "        criteria = rule['criteria']\n",
    "        for rule_criteria in criteria:\n",
    "            criteria_type = rule_criteria['type']\n",
    "            metadata = rule_criteria['metadata']\n",
    "            values = rule_criteria['values']\n",
    "            print(f\"\\t\\t{metadata} {criteria_type} {values}\")\n",
    "        ids = rule['actions']['ids']\n",
    "        print(f\"\\tPinned ids: {ids}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "138eabe8-8abf-414b-8c36-a7bc58537348",
   "metadata": {},
   "source": [
    "## Normal search without using the query rules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "7c7bc253-eeda-44b9-8075-b15ce2ac5350",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ID: eu1\n",
      "Name: PureJuice Pro - Wireless Charger suitable for European plugs\n",
      "Description: PureJuice Pro: Elevating wireless charging. Combining unparalleled charging speeds with elegant design, it promises both rapid and dependable energy for your devices. Embrace the future of wireless charging.\n",
      "Price: 18.0\n",
      "Currency: EUR\n",
      "Plug type: C\n",
      "Voltage: 230V\n",
      "Score: 14.5004\n",
      "\n",
      "ID: preview1\n",
      "Name: PureJuice Pro - Pre-order next version\n",
      "Description: Newest version of the PureJuice Pro wireless charger, coming soon! The newest model of the PureJuice Pro boasts a 2x faster charge than the current model, and a sturdier cable with an eighteen month full warranty. We also have a battery backup to charge on-the-go, up to two full charges. Pre-order yours today!\n",
      "Price: 36.0\n",
      "Currency: USD\n",
      "Plug type: ['B', 'C', 'G']\n",
      "Voltage: ['230V', '120V']\n",
      "Score: 1.0668641\n",
      "\n",
      "ID: us1\n",
      "Name: PureJuice Pro\n",
      "Description: PureJuice Pro: Experience the pinnacle of wireless charging. Blending rapid charging tech with sleek design, it ensures your devices are powered swiftly and safely. The future of charging is here.\n",
      "Price: 15.0\n",
      "Currency: USD\n",
      "Plug type: B\n",
      "Voltage: 120v\n",
      "Score: 0.11306982\n",
      "\n",
      "ID: uk1\n",
      "Name: PureJuice Pro - UK Compatible\n",
      "Description: PureJuice Pro: Redefining wireless charging. Seamlessly merging swift charging capabilities with a refined aesthetic, it guarantees your devices receive rapid and secure power. Welcome to the next generation of charging.\n",
      "Price: 20.0\n",
      "Currency: GBP\n",
      "Plug type: G\n",
      "Voltage: 230V\n",
      "Score: 0.11306982\n"
     ]
    }
   ],
   "source": [
    "response = client.search(index=\"products_index\", query={\n",
    "    \"multi_match\": {\n",
    "        \"query\": \"reliable wireless charger for iPhone\",\n",
    "        \"fields\": [ \"name^5\", \"description\" ]\n",
    "    }\n",
    "})\n",
    "\n",
    "pretty_response(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc766a09-6dab-414d-b6e2-b5e98e56d263",
   "metadata": {},
   "source": [
    "## Creating rules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "80d3a669-4e1e-4038-b90b-1285df61692d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ObjectApiResponse({'result': 'created'})"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "client.query_ruleset.put(ruleset_id=\"promotion-rules\", rules=[\n",
    "    {\n",
    "      \"rule_id\": \"us-charger\",\n",
    "      \"type\": \"pinned\",\n",
    "      \"criteria\": [\n",
    "        {\n",
    "          \"type\": \"contains\",\n",
    "          \"metadata\": \"my_query\",\n",
    "          \"values\": [\"wireless charger\"]\n",
    "        },\n",
    "        {\n",
    "          \"type\": \"exact\",\n",
    "          \"metadata\": \"country\",\n",
    "          \"values\": [\"us\"]\n",
    "        }\n",
    "      ],\n",
    "      \"actions\": {\n",
    "        \"ids\": [\n",
    "          \"us1\"\n",
    "        ]\n",
    "      }\n",
    "    },\n",
    "    {\n",
    "      \"rule_id\": \"uk-charger\",\n",
    "      \"type\": \"pinned\",\n",
    "      \"criteria\": [\n",
    "        {\n",
    "          \"type\": \"contains\",\n",
    "          \"metadata\": \"my_query\",\n",
    "          \"values\": [\"wireless charger\"]\n",
    "        },\n",
    "        {\n",
    "          \"type\": \"exact\",\n",
    "          \"metadata\": \"country\",\n",
    "          \"values\": [\"uk\"]\n",
    "        }\n",
    "      ],\n",
    "      \"actions\": {\n",
    "        \"ids\": [\n",
    "          \"uk1\"\n",
    "        ]\n",
    "      }\n",
    "    }\n",
    "  ])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5736095a-56cc-4011-a95e-d3b576c3a186",
   "metadata": {},
   "source": [
    "## Search with query rules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ba4f240e-6d84-457d-a92b-4f4da51fd2de",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ruleset ID: promotion-rules\n",
      "\n",
      "Rule ID: us-charger\n",
      "\tType: pinned\n",
      "\tCriteria:\n",
      "\t\tmy_query contains ['wireless charger']\n",
      "\t\tcountry exact ['us']\n",
      "\tPinned ids: ['us1']\n",
      "\n",
      "Rule ID: uk-charger\n",
      "\tType: pinned\n",
      "\tCriteria:\n",
      "\t\tmy_query contains ['wireless charger']\n",
      "\t\tcountry exact ['uk']\n",
      "\tPinned ids: ['uk1']\n"
     ]
    }
   ],
   "source": [
    "response = client.query_ruleset.get(ruleset_id=\"promotion-rules\")\n",
    "pretty_ruleset(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "932522c5-e21b-46d5-80d1-89c4352a979e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ID: us1\n",
      "Name: PureJuice Pro\n",
      "Description: PureJuice Pro: Experience the pinnacle of wireless charging. Blending rapid charging tech with sleek design, it ensures your devices are powered swiftly and safely. The future of charging is here.\n",
      "Price: 15.0\n",
      "Currency: USD\n",
      "Plug type: B\n",
      "Voltage: 120v\n",
      "Score: 1.7014122e+38\n",
      "\n",
      "ID: eu1\n",
      "Name: PureJuice Pro - Wireless Charger suitable for European plugs\n",
      "Description: PureJuice Pro: Elevating wireless charging. Combining unparalleled charging speeds with elegant design, it promises both rapid and dependable energy for your devices. Embrace the future of wireless charging.\n",
      "Price: 18.0\n",
      "Currency: EUR\n",
      "Plug type: C\n",
      "Voltage: 230V\n",
      "Score: 14.5004\n",
      "\n",
      "ID: preview1\n",
      "Name: PureJuice Pro - Pre-order next version\n",
      "Description: Newest version of the PureJuice Pro wireless charger, coming soon! The newest model of the PureJuice Pro boasts a 2x faster charge than the current model, and a sturdier cable with an eighteen month full warranty. We also have a battery backup to charge on-the-go, up to two full charges. Pre-order yours today!\n",
      "Price: 36.0\n",
      "Currency: USD\n",
      "Plug type: ['B', 'C', 'G']\n",
      "Voltage: ['230V', '120V']\n",
      "Score: 1.0668641\n",
      "\n",
      "ID: uk1\n",
      "Name: PureJuice Pro - UK Compatible\n",
      "Description: PureJuice Pro: Redefining wireless charging. Seamlessly merging swift charging capabilities with a refined aesthetic, it guarantees your devices receive rapid and secure power. Welcome to the next generation of charging.\n",
      "Price: 20.0\n",
      "Currency: GBP\n",
      "Plug type: G\n",
      "Voltage: 230V\n",
      "Score: 0.11306982\n"
     ]
    }
   ],
   "source": [
    "response = client.search(index=\"products_index\", query={\n",
    "      \"rule_query\": {\n",
    "          \"organic\": {\n",
    "              \"multi_match\": {\n",
    "                  \"query\": \"reliable wireless charger for iPhone\",\n",
    "                  \"fields\": [ \"name^5\", \"description\" ]\n",
    "              }\n",
    "          },\n",
    "          \"match_criteria\": {\n",
    "            \"my_query\": \"reliable wireless charger for iPhone\",\n",
    "            \"country\": \"us\"\n",
    "          },\n",
    "          \"ruleset_id\": \"promotion-rules\"\n",
    "      }\n",
    "})\n",
    "\n",
    "pretty_response(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77cdfc9b-f654-4b3f-b005-4361e6002d5b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python_3.11",
   "language": "python",
   "name": "python_3.11"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
